home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Dev / gcc263-src.lha / gcc-2.6.3 / genmultilib < prev    next >
Text File  |  1994-06-15  |  8KB  |  242 lines

  1. #!/bin/sh 
  2. # Generates multilib.h.
  3. #   Copyright (C) 1994 Free Software Foundation, Inc.
  4.  
  5. #This file is part of GNU CC.
  6.  
  7. #GNU CC is free software; you can redistribute it and/or modify
  8. #it under the terms of the GNU General Public License as published by
  9. #the Free Software Foundation; either version 2, or (at your option)
  10. #any later version.
  11.  
  12. #GNU CC is distributed in the hope that it will be useful,
  13. #but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. #GNU General Public License for more details.
  16.  
  17. #You should have received a copy of the GNU General Public License
  18. #along with GNU CC; see the file COPYING.  If not, write to
  19. #the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  
  21. # This shell script produces a header file which the gcc driver
  22. # program uses to pick which library to use based on the machine
  23. # specific options that it is given.
  24.  
  25. # The first argument is a list of sets of options.  The elements in
  26. # the list are separated by spaces.  Within an element, the options
  27. # are separated by slashes.  No leading dash is used on the options.
  28. # Each option in a set is mutually incompatible with all other options
  29. # in the set.
  30.  
  31. # The optional second argument is a list of subdirectory names.  If
  32. # the second argument is non-empty, there must be as many elements in
  33. # the second argument as there are options in the first argument.  The
  34. # elements in the second list are separated by spaces.  If the second
  35. # argument is empty, the option names will be used as the directory
  36. # names.
  37.  
  38. # The optional third argument is a list of options which are
  39. # identical.  The elements in the list are separated by spaces.  Each
  40. # element must be of the form OPTION=OPTION.  The first OPTION should
  41. # appear in the first argument, and the second should be a synonym for
  42. # it.
  43.  
  44. # The output looks like
  45. #   #define MULTILIB_MATCHES "\
  46. #   SUBDIRECTORY OPTIONS;\
  47. #   ...
  48. #   "
  49. # The SUBDIRECTORY is the subdirectory to use.  The OPTIONS are
  50. # multiple options separated by spaces.  Each option may start with an
  51. # exclamation point.  gcc will consider each line in turn.  If none of
  52. # the options beginning with an exclamation point are present, and all
  53. # of the other options are present, that subdirectory will be used.
  54. # The order of the subdirectories is such that they can be created in
  55. # order; that is, a subdirectory is preceded by all its parents.
  56.  
  57. # Here is a example (this is simplified from the actual 680x0 case):
  58. #   genmultilib "m68000/m68020 msoft-float" "m68000 m68020 msoft-float"
  59. #        "m68000=mc68000"
  60. # This produces:
  61. #   #define MULTILIB_MATCHES "\
  62. #   m68000/msoft-float m68000 msoft-float;\
  63. #   m68000/msoft-float mc68000 msoft-float;\
  64. #   m68020/msoft-float m68020 msoft-float;\
  65. #   msoft-float !m68000 !mc68000 !m68020 msoft-float;\
  66. #   m68000 m68000 !msoft-float;\
  67. #   m68000 mc60000 !msoft-float;\
  68. #   m68020 m68020 !msoft-float;\
  69. #   . !m68000 !mc68000 !m68020 !msoft-float;\
  70. #   "
  71. # The effect is that `gcc -msoft-float' (for example) will append
  72. # msoft-float to the directory name when searching for libraries or
  73. # startup files, and `gcc -m68000 -msoft-float' (for example) will
  74. # append m68000/msoft-float.
  75.  
  76. # Copy the positional parameters into variables.
  77. options=$1
  78. dirnames=$2
  79. matches=$3
  80.  
  81. # What we want to do is select all combinations of the sets in
  82. # options.  Each combination which includes a set of mutually
  83. # exclusive options must then be output multiple times, once for each
  84. # item in the set.  Selecting combinations is a recursive process.
  85. # Since not all versions of sh support functions, we achieve recursion
  86. # by creating a temporary shell script which invokes itself.
  87. rm -f tmpmultilib
  88. cat >tmpmultilib <<\EOF
  89. #!/bin/sh
  90. # This recursive script basically outputs all combinations of its
  91. # input arguments, handling mutually exclusive sets of options by
  92. # repetition.  When the script is called, ${initial} is the list of
  93. # options which should appear before all combinations this will
  94. # output.  The output looks like a list of subdirectory names with
  95. # leading and trailing slashes.
  96. if [ "$#" != "0" ]; then
  97.   first=$1
  98.   shift
  99.   for opt in `echo $first | sed -e 's|/| |'g`; do
  100.     echo ${initial}${opt}/
  101.   done
  102.   ./tmpmultilib $@
  103.   for opt in `echo $first | sed -e 's|/| |'g`; do
  104.     initial="${initial}${opt}/" ./tmpmultilib $@
  105.   done
  106. fi
  107. EOF
  108. chmod +x tmpmultilib
  109.  
  110. combinations=`initial=/ ./tmpmultilib ${options}`
  111.  
  112. rm -f tmpmultilib
  113.  
  114. # Construct a sed pattern which will convert option names to directory
  115. # names.
  116. todirnames=
  117. if [ -n "${dirnames}" ]; then
  118.   set x ${dirnames}
  119.   shift
  120.   for set in ${options}; do
  121.     for opt in `echo ${set} | sed -e 's|/| |'g`; do
  122.       if [ "$1" != "${opt}" ]; then
  123.         todirnames="${todirnames} -e s|/${opt}/|/${1}/|g"
  124.       fi
  125.       shift
  126.     done
  127.   done
  128. fi
  129.  
  130. # Construct a sed pattern which will add negations based on the
  131. # matches.  The semicolons are easier than getting the shell to accept
  132. # quoted spaces when expanding a variable.
  133. matchnegations=
  134. for i in ${matches}; do
  135.   l=`echo $i | sed -e 's/=.*$//'`
  136.   r=`echo $i | sed -e 's/^.*=//'`
  137.   matchnegations="${matchnegations} -e s/;!${l};/;!${l};!${r};/"
  138. done
  139.  
  140. # We need another recursive shell script to correctly handle positive
  141. # matches.  If we are invoked as
  142. #   genmultilib "opt1 opt2" "" "opt1=nopt1 opt2=nopt2"
  143. # we must output
  144. #   opt1/opt2 opt1 opt2
  145. #   opt1/opt2 nopt1 opt2
  146. #   opt1/opt2 opt1 nopt2
  147. #   opt1/opt2 nopt1 nopt2
  148. # In other words, we must output all combinations of matches.
  149. rm -f tmpmultilib2
  150. cat >tmpmultilib2 <<\EOF
  151. #!/bin/sh
  152. # The positional parameters are a list of matches to consider.
  153. # ${dirout} is the directory name and ${optout} is the current list of
  154. # options.
  155. if [ "$#" = "0" ]; then
  156.   echo "${dirout} ${optout};\\"
  157. else
  158.   first=$1
  159.   shift
  160.   dirout="${dirout}" optout="${optout}" ./tmpmultilib2 $@
  161.   l=`echo ${first} | sed -e 's/=.*$//'`
  162.   r=`echo ${first} | sed -e 's/^.*=//'`
  163.   case " ${optout} " in
  164.   *" ${l} "*)
  165.     newopt=`echo " ${optout} " | sed -e "s/ ${l} / ${r} /" -e 's/^ //' -e 's/ $//'`
  166.     dirout="${dirout}" optout="${newopt}" ./tmpmultilib2 $@
  167.     ;;
  168.   esac
  169. fi
  170. EOF
  171. chmod +x tmpmultilib2
  172.  
  173. # We are ready to start output.
  174. echo '#define MULTILIB_SELECT "\'
  175.  
  176. # Start with the current directory, which includes only negations.
  177. optout=
  178. for set in ${options}; do
  179.   for opt in `echo ${set} | sed -e 's|/| |'g`; do
  180.     optout="${optout} !${opt}"
  181.   done
  182. done
  183. optout=`echo ${optout} | sed -e 's/^ //'`
  184. if [ -n "${matchnegations}" ]; then
  185.   optout=`echo ";${optout};" | sed -e 's/ /;/g' ${matchnegations} -e 's/^;//' -e 's/;$//' -e 's/;/ /g'`
  186. fi
  187. echo ". ${optout};\\"
  188.  
  189. # Work over the list of combinations.  We have to translate each one
  190. # to use the directory names rather than the option names, we have to
  191. # include the information in matches, and we have to generate the
  192. # correct list of options and negations.
  193. for combo in ${combinations}; do
  194.   # Use the directory names rather than the option names.
  195.   if [ -n "${todirnames}" ]; then
  196.     dirout=`echo ${combo} | sed ${todirnames}`
  197.   else
  198.     dirout=${combo}
  199.   fi
  200.   # Remove the leading and trailing slashes.
  201.   dirout=`echo ${dirout} | sed -e 's|^/||' -e 's|/$||g'`
  202.  
  203.   # Look through the options.  We must output each option that is
  204.   # present, and negate each option that is not present.  If an
  205.   # element of a set is present, we need not negate the other elements
  206.   # of the set.
  207.   optout=
  208.   for set in ${options}; do
  209.     setopts=`echo ${set} | sed -e 's|/| |g'`
  210.     found=
  211.     for opt in ${setopts}; do
  212.       case "${combo}" in
  213.       *"/${opt}/"*)
  214.     optout="${optout} ${opt}"
  215.     found=yes
  216.     ;;
  217.       esac
  218.     done
  219.     if [ "${found}" = "" ]; then
  220.       for opt in ${setopts}; do
  221.     optout="${optout} !${opt}"
  222.       done
  223.     fi
  224.   done
  225.   optout=`echo ${optout} | sed -e 's/^ //'`
  226.  
  227.   # Add any negations of matches.
  228.   if [ -n "${matchnegations}" ]; then
  229.     optout=`echo ";${optout};" | sed -e 's/ /;/g' ${matchnegations} -e 's/^;//' -e 's/;$//' -e 's/;/ /g'`
  230.   fi
  231.  
  232.   # Output the line with all appropriate matches.
  233.   dirout="${dirout}" optout="${optout}" ./tmpmultilib2 ${matches}
  234. done
  235.  
  236. rm -f tmpmultilib2
  237.  
  238. # That's it.
  239. echo '"'
  240.  
  241. exit 0
  242.